package com.ld.security.common.mybatis.wrapper;

import com.ld.security.common.core.constant.CSuperConstant;
import com.ld.security.common.core.util.ReflectionUtil;
import com.ld.security.common.core.util.SimpDateUtil;
import com.ld.security.common.core.util.StringUtil;
import com.ld.security.common.mybatis.constant.DateTypeConstant;
import com.ld.security.common.mybatis.constant.SqlCondition;
import com.ld.security.common.mybatis.util.TypeUtil;

import java.util.*;

/**
 * 实体sql构造器
 */
public abstract class AbstQueryWrapper implements SqlWrapper {

    protected String dataSource;

    //其他参数对象
    protected Map map = new HashMap();


    protected String columnSql = "";

    protected String fromSql = "";

    protected String whereSql = "";

    protected String groupSql ="";

    protected String havingSql="";

    protected String orderSql="";

    private static String argName="arg";

    private static String mapName="map";

    private int i=0;


    protected void init(){

        this.getColumnSql();
        this.getFormSql();
        this.getWhereSql();
        this.getGroupSql();
        this.getHavingSql();
        this.getOrderSql();

    }



    protected abstract String getColumnSql();






    public abstract String getFormSql();


    protected String getValue(String name,SqlCondition sqlCondition, Object val){
        if(sqlCondition == SqlCondition.anon){
            return "";
        }
        if(val instanceof Collection){
            Collection cols = (Collection)val;
            LinkedList list = new LinkedList<>();
            for (Object col : cols) {
                if(col instanceof Date){
                    String f = SimpDateUtil.fomat((Date) col);
                    col = f;
                }else if(col instanceof CSuperConstant.EnSuperEnum){
                    CSuperConstant.EnSuperEnum se = ( CSuperConstant.EnSuperEnum)col;
                    col =se.getValue();
                }
                list.add(col);
            }
            val = list;
        }

        //怀疑这个是日期
        if(sqlCondition == SqlCondition.between){
            if(val instanceof String){
                List vs = TypeUtil.getDateList(val.toString());
                if(vs != null){
                    val = vs;
                }
            }
        }
        if(val instanceof CSuperConstant.EnSuperEnum){
            CSuperConstant.EnSuperEnum se = ( CSuperConstant.EnSuperEnum)val;
            val =se.getValue();
        }


        String key = name.replaceAll("\\.","");
        key+=i++;

        StringBuffer sb = new StringBuffer();
        if(sqlCondition == SqlCondition.like){
            this.map.put(key,"%"+val+"%");
        }else if(sqlCondition == SqlCondition.like_right){
            this.map.put(key,val+"%");
        }else if(sqlCondition == SqlCondition.like_left){
            this.map.put(key,"%"+val);
        }else{
            this.map.put(key,val);
        }
       sb.append(name+" "+ sqlCondition.getLabel()+" ");
        switch (sqlCondition){
            case in:{
                Collection cols =( Collection)val;
                int i = 0;
                sb.append("(");

                while(i<cols.size()){
                    if(i>0){
                        sb.append(",");
                    }
                    sb.append(" #{"+SqlWrapper.name+"."+mapName+"."+key+"["+i+"]}");
                    i++;
                }
                sb.append(") ");
                break;


            }
            case between:{
                if(val instanceof Collection){
                    sb.append(" between ");
                    sb.append(" #{"+SqlWrapper.name+"."+mapName+"."+key+"[0]}");
                    sb.append(" and ");
                    sb.append(" #{"+SqlWrapper.name+"."+mapName+"."+key+"[1]}");
                }

                break;
            }
            case ne:{
                sb.append(" #{"+SqlWrapper.name+"."+mapName+"."+key+"}");
                break;
            }
            default:{
                sb.append(" #{"+SqlWrapper.name+"."+mapName+"."+key+"}");
                break;

            }

        }
        return sb.toString();
    }



    protected abstract String getWhereSql() ;

    public abstract String getGroupSql();



    public abstract String getHavingSql();

    public abstract String getOrderSql();

    @Override
  public String getSql() {
            String sql="";
            sql += "select "+columnSql +" ";
            sql += " from "+fromSql+" ";

            if (StringUtil.isNotNull(whereSql)) {
              sql += " where  " + whereSql;
            }
            if (StringUtil.isNotNull(groupSql)) {
              sql += " group by " + groupSql;
            }
            if (StringUtil.isNotNull(havingSql)) {
              sql += " having  " + havingSql;
            }
            if(StringUtil.isNotNull(orderSql)){
                sql += " order by  " + orderSql;
            }
            return sql;
        }



    public AbstQueryWrapper where(String name, SqlCondition sqlCondition, Object val) {
        return where(name,name,sqlCondition,val);
    }

        public AbstQueryWrapper where(String name, String key, SqlCondition sqlCondition, Object val){
        if(ReflectionUtil.isNull(val)){
            return this;
        }
        if(StringUtil.isNull(whereSql)){
            whereSql=" ";
        }else{
            whereSql+=" and ";
        }



        whereSql+= this.getValue(name,sqlCondition,val);


        return this;
    }

    public Map getMap() {
        return map;
    }



    @Override
    public String getDataSource() {
        return dataSource;
    }

    public void setDataSource(String dataSource) {
        this.dataSource = dataSource;
    }
}